﻿using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Microsoft.Practices.Unity.InterceptionExtension;
using System.Collections;

namespace Framework.IOC
{
    public class UnityIOCContainer : IDIContainer
    {
        private readonly  IUnityContainer _unityContainer = new UnityContainer();
        public UnityIOCContainer()
        {
            //添加拦截
            _unityContainer.AddNewExtension<Interception>();
        }
        
        #region 注入
        public IDIContainer RegisterInstance(Type t, object instance)
        {
            if (_unityContainer.IsRegistered(t)) return this;
            _unityContainer.RegisterInstance(t, instance);
            return this;
        }

        public IDIContainer RegisterType(Type from, Type to, params RegisterArguments[] registerArguments)
        {
            if (_unityContainer.IsRegistered(from)) return this;

            if (registerArguments != null)
            {
                List<InjectionMember> interceptionList = new List<InjectionMember>();
                interceptionList.Add(new Interceptor<InterfaceInterceptor>());
                foreach (var arg in registerArguments)
                {
                    if (arg.ArgType == ArgType.Interception)
                    {
                        interceptionList.Add(new InterceptionBehavior(arg.Type));
                    }
                }
                _unityContainer.RegisterType(from, to,interceptionList.ToArray());
            }
            else
            {
                _unityContainer.RegisterType(from, to);
            }
            return this;
        }
        #endregion
        #region Private Methods
        /// <summary>
        /// 动态加载
        /// </summary>
        private void LoadDynamicType(IUnityContainer _container)
        {
            ////unity动态类型注入，各个程序集用,分开，支持*通配符号
            //string unityDynamicAssembly = System.Configuration.ConfigurationManager.AppSettings["unityDynamicAssembly"];
            ////是否同时启动数据集缓存策略
            //string unityCachingDoing = System.Configuration.ConfigurationManager.AppSettings["unityCachingDoing"];
            //InjectionMember[] injectionMembers = null;
            //if (unityCachingDoing == "1")
            //{
            //    injectionMembers = new InjectionMember[] { new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<Project.UnityCaching.CachingBehavior>() };
            //}
            //if (!string.IsNullOrWhiteSpace(unityDynamicAssembly))
            //{
            //    Array.ForEach(unityDynamicAssembly.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), dllName =>
            //    {
            //        var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            //        if (System.Web.HttpContext.Current != null)
            //        {
            //            baseDir += "bin";
            //        }
            //        var files = Directory.GetFiles(baseDir, dllName);
            //        var iTypes = new List<Type>();
            //        foreach (var file in files)
            //        {
            //            var interfaceASM = Assembly.LoadFrom(Path.Combine(baseDir, file));
            //            var types = from t in interfaceASM.GetTypes()
            //                        where !string.IsNullOrWhiteSpace(t.Namespace)
            //                        select t;

            //            foreach (var type in types)
            //            {
            //                if (type.GetInterfaces() != null && type.GetInterfaces().Any())
            //                    foreach (var father in type.GetInterfaces())
            //                    {
            //                        _container.RegisterType(father
            //                            , type
            //                            , injectionMembers);
            //                    }
            //            }
            //        }
            //    });

            //}

        }
        private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments)
        {
            List<ParameterOverride> overrides = new List<ParameterOverride>();
            Type argumentsType = overridedArguments.GetType();
            argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                .ToList()
                .ForEach(property =>
                {
                    var propertyValue = property.GetValue(overridedArguments, null);
                    var propertyName = property.Name;
                    overrides.Add(new ParameterOverride(propertyName, propertyValue));
                });
            return overrides;
        }
        #endregion


        #region IServiceProvider Members
        /// <summary>
        /// Gets the service instance with the given type.
        /// </summary>
        /// <param name="serviceType">The type of the service.</param>
        /// <returns>The service instance.</returns>
        public object GetService(Type serviceType)
        {
            return _unityContainer.Resolve(serviceType);
        }

        #endregion

        #region 获取
        public T Resolve<T>()
        {
            return this._unityContainer.Resolve<T>();
        }
        
        #endregion

        public dynamic GetContainerObjcet()
        {
            return this._unityContainer;
        }
    }
}



